
/**
 * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#pragma once

#include "esp_video_codec_types.h"
#include "esp_video_enc.h"
#include "esp_video_dec.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef struct {
    esp_video_codec_pixel_fmt_t  enc_in_fmt;
    esp_video_codec_pixel_fmt_t  dec_out_fmt;
    esp_video_codec_resolution_t res;
    uint8_t                     *raw_data;
    uint32_t                     raw_size;
    uint8_t                     *encoded_data;
    uint32_t                     encoded_size;
    uint8_t                     *decoded_data;
    uint32_t                     decoded_size;
    bool                         vertical;
    uint8_t                      bar_count;
} video_codec_test_res_t;

typedef struct {
    esp_video_codec_pixel_fmt_t fmt;
    esp_video_codec_desc_t      desc;
} test_codec_info_t;

extern video_codec_test_res_t test_res;

/**
 * @brief 测试单帧视频解码功能
 * 
 * @param dec_info 解码器信息结构体，包含编解码器类型、格式等配置
 * @return int 0表示成功，-1表示失败
 * 
 * @note 调用此函数前需要：
 *       1. 调用 esp_video_dec_register_default() 注册默认解码器
 *       2. 确保 test_res.encoded_data 和 test_res.encoded_size 包含有效的编码数据
 *       3. 确保 test_res.decoded_data 和 test_res.decoded_size 已分配足够的解码缓冲区
 */
int video_decoder_test_one_frame(test_codec_info_t *dec_info);

/**
 * @brief 初始化视频编解码器测试资源
 * 
 * @param enc_info 编码器信息，可以为NULL（仅解码时）
 * @param dec_info 解码器信息，可以为NULL（仅编码时）
 * @param resolution 视频分辨率
 * @return int 0表示成功，-1表示失败
 */
int prepare_test_res(test_codec_info_t *enc_info, test_codec_info_t *dec_info, 
                     esp_video_codec_resolution_t *resolution);

/**
 * @brief 释放视频编解码器测试资源
 */
void release_test_res(void);

void test_video_codec();

/**
 * @brief 准备JPEG解码器资源，从SD卡或内置数据加载JPEG文件
 * 
 * @param dec_info 解码器信息配置
 * @param resolution 期望的分辨率（可为NULL使用默认值）
 */
void prepare_decoder_jpeg_res(test_codec_info_t *dec_info,
                             esp_video_codec_resolution_t *resolution);
/**
 * @brief JPEG解码并显示到屏幕
 * 
 * @param dec_info 解码器信息配置
 * @return int 0表示成功，-1表示失败
 */
int decode_jpeg_and_display(test_codec_info_t *dec_info);

/**
 * @brief 显示解码后的图像到屏幕
 * 
 * @return int 0表示成功，-1表示失败
 */
int display_decoded_image(void);

/**
 * @brief 使用LVGL显示解码后的图像
 * 
 * @return int 0表示成功，-1表示失败
 */
int display_image_with_lvgl(void);

/**
 * @brief 扩展版本的LVGL图像显示函数，支持视频播放模式
 * 
 * @param is_video_mode 是否为视频播放模式
 * @param current_frame 当前帧索引
 * @param total_frames 总帧数
 * @return int 0表示成功，-1表示失败
 */
int display_image_with_lvgl_ex(bool is_video_mode, int current_frame, int total_frames);

/**
 * @brief 清理LVGL显示对象
 */
void cleanup_lvgl_display(void);

/**
 * @brief 测试JPEG解码完整流程
 * 
 * 包含：资源准备、解码、显示、资源清理
 */
void test_jpeg_decode(void);

int prepare_decoder_only_res(test_codec_info_t *dec_info, 
                             esp_video_codec_resolution_t *resolution);

// 多帧JPEG解码相关函数
int decode_multiple_jpeg_frames(test_codec_info_t *dec_info, const char* base_path, int frame_count);
void test_multiple_jpeg_decode(void);

// 预加载JPEG播放相关函数
typedef struct {
    uint8_t *data;          // JPEG数据指针
    size_t size;            // JPEG数据大小
    char filename[64];      // 文件名
    bool valid;             // 数据是否有效
} jpeg_frame_buffer_t;
typedef enum { 
    Display1 = 0,
    Display2,

} DisplayCmdMsgType;

typedef struct {
    uint16_t type;
    uint16_t frame_idx;//当前帧数
    uint16_t frame_count;//要播放的总帧数播放间隔
}DisplayCmdMsgInfo;//img表情消息


// 预解码帧缓存结构体
typedef struct {
    uint8_t *decoded_data;                      // 解码后的像素数据（存储在PSRAM中）
    uint32_t decoded_size;                      // 解码数据大小
    esp_video_codec_resolution_t resolution;    // 图像分辨率
    esp_video_codec_pixel_fmt_t pixel_format;   // 像素格式
    uint32_t frame_index;                       // 帧索引
    bool valid;                                // 数据有效性标志
    char source_filename[64];                   // 源文件名（调试用）
} predecoded_frame_t;

// 解码帧队列结构体
typedef struct {
    uint8_t *decoded_data;                      // 解码后的像素数据
    uint32_t decoded_size;                      // 解码数据大小
    esp_video_codec_resolution_t resolution;    // 图像分辨率
    esp_video_codec_pixel_fmt_t pixel_format;   // 像素格式
    uint32_t frame_index;                       // 帧索引
    uint32_t pts;                              // 显示时间戳
    bool valid;                                // 数据有效性标志
} decoded_frame_t;

// 视频播放器配置
typedef struct {
    QueueHandle_t frame_queue;      // 解码帧队列
    TaskHandle_t decode_task;       // 解码任务句柄
    TaskHandle_t display_task;      // 显示任务句柄
    bool stop_playback;             // 停止播放标志
    uint32_t target_fps;            // 目标帧率
    uint32_t frame_delay_ms;        // 帧间延迟（毫秒）
    jpeg_frame_buffer_t *frame_buffers;  // 预加载的JPEG帧缓冲区
    int total_frames;               // 总帧数
    bool loop_playback;             // 是否循环播放
} video_player_config_t;

int preload_jpeg_frames(const char* base_path, int frame_count, jpeg_frame_buffer_t **frame_buffers, int *loaded_count);
void free_preloaded_frames(jpeg_frame_buffer_t *frame_buffers, int frame_count);
int decode_preloaded_jpeg_frames(test_codec_info_t *dec_info, jpeg_frame_buffer_t *frame_buffers, int frame_count);
void test_preloaded_jpeg_playback(void *arg);
void InitializeDisplayTask();
void decode_task(void);
void preload_two_jpeg_freams();
#ifdef __cplusplus
}
#endif
